const { ccclass, property } = cc._decorator;

import n from "./frameworkManager"
import l from "./NodePool"
import s from "./MatchGameConfig"
import MatchGameConfig from "./MatchGameConfig";


@ccclass
class MatchAniCtrl {
    destoryAniParent = null;
    matchDestoryItem = null;
    matchEffectItem = null;
    exchangePrefab = null;
    matchBoomPrefab = null;

    isReady = false;

    static _instance = null;

    static getInstance():MatchAniCtrl {
        if (!this._instance) {
            this._instance = new MatchAniCtrl();
        }
        return this._instance;
    }

    ready(destoryAniParent, matchDestoryItem, matchEffectItem) {
        this.isReady = true;
        this.matchDestoryItem = matchDestoryItem;
        l.initPool(this.matchDestoryItem, 0, s.MatchAniPool.MatchDestoryItem);
        this.matchEffectItem = matchEffectItem;
        l.initPool(this.matchEffectItem, 0, s.MatchAniPool.matchEffectItem);
        this.destoryAniParent = destoryAniParent;
    }

    async init() {
        await this.loadExchangeSpData();
    }

    loadExchangeSpData() {
        return new Promise((resolve, reject) => {
            cc.resources.load("prefabs/exchangeSquarePrefab", cc.Prefab, (err, prefab) => {
                if (err) {
                    n.log("加载单个道具使用动画数据报错", err);
                    reject();
                }
                this.exchangePrefab = prefab;
                l.initPool(this.exchangePrefab, 0, s.MatchAniPool.squareExchange);
                resolve(true);
            });
        });
    }

    setMatchAniSkin(itemType) {
        let skin = "";
        switch (itemType) {
            case s.MatchItemType.blueShield:
                skin = "DunPai";
                break;
            case s.MatchItemType.greenLeaf:
                skin = "YeZi";
                break;
            case s.MatchItemType.purpleGem:
                skin = "ZuanShi";
                break;
            case s.MatchItemType.redBook:
                skin = "Shu";
                break;
            case s.MatchItemType.yellowCrown:
                skin = "HuangGuan";
                break;
        }
        return skin;
    }

    getMatchDestoryAniSkin(itemType) {
        let skin = "";
        switch (itemType) {
            case s.MatchItemType.blueShield:
                skin = "DuPai";
                break;
            case s.MatchItemType.greenLeaf:
                skin = "YeZi";
                break;
            case s.MatchItemType.purpleGem:
                skin = "ZuanShi";
                break;
            case s.MatchItemType.redBook:
                skin = "Shu";
                break;
            case s.MatchItemType.yellowCrown:
                skin = "HuangGuan";
                break;
        }
        return skin;
    }

    playIdleAni(item:sp.Skeleton) {
        item.node.x = item.node.y = 0;
        item.setAnimation(0, "idle_1", false);
    }

    playBreathAni(item) {
        item.node.x = item.node.y = 0;
        item.setAnimation(0, "breathe", true);
    }

    playLightingAni(item) {
        item.node.x = item.node.y = 0;
        item.setAnimation(0, "Checked", true);
    }

    playMatchRemoveAni(item, callback) {
        item.clearTracks();
        item.setAnimation(0, "remove", false);
        item.setCompleteListener(() => {
            item.setCompleteListener(null);
            if (callback) {
                callback();
            }
        });
    }

    playDestoryAni(item, position) {
        let itemType = item.itemType;
        let node = l.getNode(s.MatchAniPool.MatchDestoryItem);
        node.parent = this.destoryAniParent;
        node.setPosition(this.getV3Pos(position.row, position.col));
        let spineNode = node.getChildByName("destorySpine");
        let spine = spineNode.getComponent(sp.Skeleton);
        spine.clearTracks();
        spine.setSkin(this.getMatchDestoryAniSkin(itemType));
        spineNode.setPosition(cc.v3());
        spineNode.active = false;
        setTimeout(() => {
            spineNode.active = true;
            spine.setCompleteListener(() => {
                spine.setCompleteListener(null);
                node.stopAllActions();
                l.putNode(s.MatchAniPool.MatchDestoryItem, node);
            });
            spine.setAnimation(0, "Remove", false);
        }, 200);
    }

    playMatchEffectAni(item, position, lastPosition, callback = null) {
        let itemType = item.itemType;
        let node = l.getNode(s.MatchAniPool.matchEffectItem);
        node.parent = this.destoryAniParent;
        node.setPosition(this.getV3Pos(position.row, position.col));
        let matchSpineNode = node.getChildByName("matchSpine");
        matchSpineNode.active = false;
        matchSpineNode.setPosition(cc.v3());
        if (lastPosition) {
            matchSpineNode.active = true;
            let spine = matchSpineNode.getComponent(sp.Skeleton);
            spine.clearTracks();
            spine.setSkin(this.setMatchAniSkin(itemType));
            spine.setAnimation(0, "idle_1", false);
            let offsetX = position.row > lastPosition.row ? -80 : 80;
            if (position.row == lastPosition.row) {
                offsetX = 0;
            }
            let offsetY = position.col > lastPosition.col ? 80 : -80;
            if (position.col == lastPosition.col) {
                offsetY = 0;
            }
            cc.tween(matchSpineNode)
                .by(0.2, { x: offsetX, y: offsetY })
                .call(() => {
                    matchSpineNode.stopAllActions();
                    matchSpineNode.active = false;
                    l.putNode(s.MatchAniPool.matchEffectItem, node);
                })
                .start();
        }
    }

    getV3Pos(row, col) {
        return cc.v3(row * MatchGameConfig.ITEM_WIDTH + MatchGameConfig.ITEM_WIDTH / 2, -col * MatchGameConfig.ITEM_HEIGHT - MatchGameConfig.ITEM_HEIGHT / 2);
    }

    playEechangeAni(item1, item2) {
        let node = l.getNode(s.MatchAniPool.squareExchange);
        node.parent = this.destoryAniParent;
        if (item1.i == item2.i) {
            node.angle = 0;
            node.position = this.getExchangePos(item1.i, Math.min(item1.j, item2.j), true);
        } else {
            node.angle = 90;
            node.position = this.getExchangePos(Math.min(item1.i, item2.i), item1.j, false);
        }
        node.getComponent(sp.Skeleton).setAnimation(0, "idle_1", false);
        node.getComponent(sp.Skeleton).setCompleteListener(() => {
            l.putNode(s.MatchAniPool.squareExchange, node);
        });
    }

    getExchangePos(i, j, vertical) {
        let pos = cc.v3(i * MatchGameConfig.ITEM_WIDTH + MatchGameConfig.ITEM_WIDTH / 2, -j * MatchGameConfig.ITEM_HEIGHT - MatchGameConfig.ITEM_HEIGHT / 2);
        if (vertical) {
            pos.y -= MatchGameConfig.ITEM_HEIGHT / 2;
        } else {
            pos.x += MatchGameConfig.ITEM_WIDTH / 2;
        }
        return pos;
    }

    playShakeAni(item) {
        item.setAnimation(0, "Checked", false);
    }
}

export default MatchAniCtrl.getInstance();